package deviceScript

import (
	"errors"
	"fmt"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
	"go-fox-edge-device/channelService"
	"go-fox-edge-device/deviceLogger"
)

type exchangeService struct {
}

func (e *exchangeService) exchange(routineKey string, deviceName string, manufacturer string, deviceType string, operateEntity *edgeEntity.OperateEntity, params map[string]interface{}, timeout int) (rnt map[string]interface{}, err error) {
	// 定义一个最终的异常拦截，用来防止可能的代码BUG
	defer func() {
		if r := recover(); r != nil {
			message := fmt.Sprintf("exchangeService.exchange() 捕获到异常:%v", r)
			err = errors.New(message)
			deviceLogger.PrintLogger(err)
		}
	}()

	if operateEntity.EngineType == "Java" {
		return nil, errors.New("不支持的类型")
	}

	// 取出ScriptEngine
	engine := engineService.getScriptEngine(manufacturer, deviceType, routineKey)

	// 取出：设备模型信息
	modelName := Map.GetOrDefault(operateEntity.EngineParam, "modelName", "").(string)

	// 取出：编码/解码信息
	encode := Map.GetOrDefault(operateEntity.EngineParam, "encode", make(map[string]interface{}))
	decode := Map.GetOrDefault(operateEntity.EngineParam, "decode", make(map[string]interface{}))
	if Method.HasEmpty(encode, decode) {
		return nil, errors.New("找不到对应操作名称的编码/解码函数：" + operateEntity.OperateName)
	}

	// 编码脚本
	encodeMain := Map.GetOrDefault(encode.(map[string]interface{}), "main", "")
	encodeScript := Map.GetOrDefault(encode.(map[string]interface{}), "code", "")
	if Method.HasEmpty(encodeMain, encodeScript) {
		return nil, errors.New("找不到对应操作名称的编码函数：" + operateEntity.OperateName)
	}

	// 解码脚本
	decodeMain := Map.GetOrDefault(decode.(map[string]interface{}), "main", "").(string)
	decodeScript := Map.GetOrDefault(decode.(map[string]interface{}), "code", "").(string)
	if Method.HasEmpty(decodeMain, decodeScript) {
		return nil, errors.New("找不到对应操作名称的解码函数：" + operateEntity.OperateName)
	}

	// 为ScriptEngine填入设备模型
	engineModel.setEnvDeviceModel(routineKey, manufacturer, deviceType, modelName, params)

	// 为ScriptEngine填入全局变量
	err = engineOperator.setSendEnvValue(engine, params)
	if err != nil {
		return nil, err
	}

	// 数据编码
	send, err := engineOperator.encode(engine, encodeMain.(string), encodeScript.(string))
	if err != nil {
		return nil, err
	}

	recv, err := channelService.Exchange(deviceName, send, timeout)
	if err != nil {
		return nil, err
	}

	// 为ScriptEngine填入全局变量
	err = engineOperator.setRecvEnvValue(engine, recv, params)
	if err != nil {
		return nil, err
	}

	// 将解码结果，根据模式，用各自的字段带回
	if EnumRecord == operateEntity.DataType {
		return engineOperator.decodeRecord(engine, operateEntity.OperateName, decodeMain, decodeScript)
	} else if EnumResult == operateEntity.DataType {
		return engineOperator.decodeResult(engine, operateEntity.OperateName, decodeMain, decodeScript)
	} else {
		return engineOperator.decodeStatus(engine, operateEntity.OperateName, decodeMain, decodeScript)
	}
}
